package org.example.seri

import com.alibaba.fastjson2.JSON
import com.baidu.bjf.remoting.protobuf.ProtobufProxy
import io.ktor.server.routing.*
import org.noear.solon.Solon
import org.noear.solon.Utils
import org.noear.solon.annotation.Component
import org.noear.solon.annotation.Controller
import org.noear.solon.annotation.Init
import org.noear.solon.annotation.Mapping
import org.noear.solon.core.handle.*
import org.noear.solon.core.route.RouterInterceptor
import org.noear.solon.core.route.RouterInterceptorChain
import org.noear.solon.lang.Nullable
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import kotlin.time.Duration

val datajCodec = ProtobufProxy.create(Dataj::class.java)

/**
 * Solon框架简单案例
 * 包含一个控制器接口、一个路由拦截器和一个全局过滤器
 */
class SolonDemo {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            Solon.start(SolonDemo::class.java, args) { app ->

            }
        }
    }
}

/**
 * 控制器类，定义API接口
 */
@Controller
@Mapping("/api")
class HelloController {
    @Mapping("/hello")
    fun hello(name: String?): Data {
        val data = Data(
            111, 222, 3333, "hello world 卡霍夫卡换卡的说法是？",
            listOf("qw", "ddd", "retert"), mapOf("qw" to "qw", "ddd" to "ddd", "retert" to "retert")
        )
        return data
    }

    @Mapping("/hello1")
    fun hello1(): Dataj {
        val data = Dataj(
            111, 222, 3333, "hello world 卡霍夫卡换卡的说法是？",
            listOf("qw", "ddd", "retert"), mapOf("qw" to "qw", "ddd" to "ddd", "retert" to "retert")
        )
        return data
    }
}

/**
 * 路由拦截器
 * 拦截所有路由请求，记录日志
 */
@Component
class RouteInterceptor : RouterInterceptor {
    override fun doIntercept(ctx: Context?, mainHandler: Handler?, chain: RouterInterceptorChain) {
        val ctx = Context.current()
        println("路由拦截器: 收到请求 ${ctx.method()} ${ctx.path()}")

        chain.doIntercept(ctx, mainHandler)

        println("路由拦截器: 请求处理完成 ${ctx.path()}")
    }

    @Throws(Throwable::class)
    override fun postResult(ctx: Context, @Nullable result: Any?): Any? {
        if(result != null && result is Dataj) {
            ctx.attrSet("@render", "@pb")
        }
        return result
    }
}

/**
 * 全局过滤器
 * 对所有请求进行过滤处理
 */
@Component
class GlobalFilter : Filter {
    val pbRender = PbRender()
    @Init
    fun init() {
        RenderManager.mapping("@pb", pbRender)
        val router = Solon.app().router()
        val collection = router.getAll(Endpoint.main)
        for (endpoint in collection) {
            println("${endpoint.path()} ${endpoint.method().name}")
        }
        println()
    }
    override fun doFilter(ctx: Context, chain: FilterChain) {
        println("过滤器: 开始处理请求 ${ctx.path()}")

        // 继续执行后续处理
        chain.doFilter(ctx)

        println("过滤器: 请求处理结束 ${ctx.path()}")
    }
}

/**
 * Protocol Buffers 渲染器
 */
class PbRender : Render {
    override fun render(obj: Any?, ctx: Context) {
        // 处理包装类型
        if(obj != null && obj is Dataj) {
            println("pb render处理了")
            val bytes = datajCodec.encode(obj)
            ctx.contentType("application/json;pb")
            ctx.outputStream().write(bytes)
            ctx.rendered = true
        } else {
            throw IllegalArgumentException("无法处理对象")
        }
    }
}

class SolonDemo1 {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val data = Dataj(
                111, 222, 3333, "hello world 卡霍夫卡换卡的说法是？",
                listOf("qw", "ddd", "retert"), mapOf("qw" to "qw", "ddd" to "ddd", "retert" to "retert")
            )
//            data.obj = Dataj(
//                111, 222, 3333, "hello world 卡霍夫卡换卡的说法是？",
//                listOf("qw", "ddd", "retert"), mapOf("qw" to "qw", "ddd" to "ddd", "retert" to "retert")
//            )
            val encode = datajCodec.encode(data)
            val decode = datajCodec.decode(encode)

            println(JSON.toJSONString(decode))

            return
            val client = HttpClient.newBuilder()
                .build()

            // 创建请求
            val request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8080/hello"))
//                .header("Accept", "application/json;pb")
                .GET()
                .build()

            try {
                // 发送请求并获取响应
                val response = client.send(request, HttpResponse.BodyHandlers.ofByteArray())

                println("Status code: ${response.statusCode()}")
                println("Headers: ${response.headers().map()}")

                // 获取二进制数据
                val binaryData = response.body()
                println("Binary data length: ${binaryData.size} bytes")

                // 尝试将数据转换为字符串
                val textData = String(binaryData, Charsets.UTF_8)
                println("Text data: $textData")

//                val dataj = datajCodec.decode(binaryData)
//                println("Dataj: ${JSON.toJSONString(dataj)}")

            } catch (e: Exception) {
                println("Error occurred: ${e.message}")
                e.printStackTrace()
            }
        }
    }
}
